package com.example.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 端口配置验证工具
 * 用于验证端口配置是否符合规范
 * 
 * @author: Allen
 * @create: 2025/7/3 23:55
 * @description: 端口配置验证
 **/
@Slf4j
@Component
public class PortConfigValidator {
    
    @Value("${server.port}")
    private int webPort;
    
    @Value("${grpc.server.port}")
    private int grpcPort;
    
    @Value("${server.id}")
    private int serverId;
    
    @Value("${spring.application.name}")
    private String serviceName;
    
    /**
     * 验证端口配置
     */
    public void validatePortConfig() {
        log.info("=== 端口配置验证 ===");
        log.info("服务名称: {}", serviceName);
        log.info("Web端口: {}", webPort);
        log.info("gRPC端口: {}", grpcPort);
        log.info("服务器ID: {}", serverId);
        
        boolean isValid = true;
        
        // 验证Web端口
        if (!isValidWebPort(serviceName, webPort)) {
            log.error("❌ Web端口配置错误: {} 应该在正确的范围内", webPort);
            isValid = false;
        } else {
            log.info("✅ Web端口配置正确: {}", webPort);
        }
        
        // 验证gRPC端口
        if (!isValidGrpcPort(serviceName, grpcPort)) {
            log.error("❌ gRPC端口配置错误: {} 应该在正确的范围内", grpcPort);
            isValid = false;
        } else {
            log.info("✅ gRPC端口配置正确: {}", grpcPort);
        }
        
        // 验证服务器ID
        if (!isValidServerId(serviceName, serverId)) {
            log.error("❌ 服务器ID配置错误: {} 应该在正确的范围内", serverId);
            isValid = false;
        } else {
            log.info("✅ 服务器ID配置正确: {}", serverId);
        }
        
        // 验证端口与服务器ID的一致性
        if (!isPortServerIdConsistent(serviceName, webPort, serverId)) {
            log.error("❌ 端口与服务器ID不一致: webPort={}, serverId={}", webPort, serverId);
            isValid = false;
        } else {
            log.info("✅ 端口与服务器ID一致: webPort={}, serverId={}", webPort, serverId);
        }
        
        if (isValid) {
            log.info("🎉 所有端口配置验证通过！");
        } else {
            log.error("❌ 端口配置验证失败，请检查配置！");
        }
        
        log.info("=== 验证完成 ===");
    }
    
    /**
     * 验证Web端口是否在正确范围内
     */
    private boolean isValidWebPort(String serviceName, int port) {
        switch (serviceName) {
            case "gate-service":
                return port >= 4000 && port <= 4099;
            case "lobby-service":
                return port >= 5000 && port <= 5099;
            case "game-service":
                return port >= 6000 && port <= 6099;
            default:
                return false;
        }
    }
    
    /**
     * 验证gRPC端口是否在正确范围内
     */
    private boolean isValidGrpcPort(String serviceName, int port) {
        switch (serviceName) {
            case "gate-service":
                return port >= 14000 && port <= 14099;
            case "lobby-service":
                return port >= 15000 && port <= 15099;
            case "game-service":
                return port >= 16000 && port <= 16099;
            default:
                return false;
        }
    }
    
    /**
     * 验证服务器ID是否在正确范围内
     */
    private boolean isValidServerId(String serviceName, int serverId) {
        switch (serviceName) {
            case "gate-service":
                return serverId >= 1001 && serverId <= 1999;
            case "lobby-service":
                return serverId >= 2001 && serverId <= 2999;
            case "game-service":
                return serverId >= 3001 && serverId <= 3999;
            default:
                return false;
        }
    }
    
    /**
     * 验证端口与服务器ID是否一致
     */
    private boolean isPortServerIdConsistent(String serviceName, int webPort, int serverId) {
        int expectedServerId = 0;
        
        switch (serviceName) {
            case "gate-service":
                expectedServerId = 1000 + (webPort - 4000) + 1;
                break;
            case "lobby-service":
                expectedServerId = 2000 + (webPort - 5000) + 1;
                break;
            case "game-service":
                expectedServerId = 3000 + (webPort - 6000) + 1;
                break;
            default:
                return false;
        }
        
        return serverId == expectedServerId;
    }
    
    /**
     * 获取端口配置信息
     */
    public void printPortConfigInfo() {
        log.info("=== 端口配置信息 ===");
        log.info("服务名称: {}", serviceName);
        log.info("Web端口: {}", webPort);
        log.info("gRPC端口: {}", grpcPort);
        log.info("服务器ID: {}", serverId);
        
        // 计算预期的服务器ID
        int expectedServerId = calculateExpectedServerId(serviceName, webPort);
        log.info("根据端口计算的预期服务器ID: {}", expectedServerId);
        
        // 计算预期的gRPC端口
        int expectedGrpcPort = calculateExpectedGrpcPort(serviceName, webPort);
        log.info("根据Web端口计算的预期gRPC端口: {}", expectedGrpcPort);
        
        log.info("=== 配置信息完成 ===");
    }
    
    /**
     * 根据服务名称和Web端口计算预期的服务器ID
     */
    private int calculateExpectedServerId(String serviceName, int webPort) {
        switch (serviceName) {
            case "gate-service":
                return 1000 + (webPort - 4000) + 1;
            case "lobby-service":
                return 2000 + (webPort - 5000) + 1;
            case "game-service":
                return 3000 + (webPort - 6000) + 1;
            default:
                return 0;
        }
    }
    
    /**
     * 根据Web端口计算预期的gRPC端口
     */
    private int calculateExpectedGrpcPort(String serviceName, int webPort) {
        switch (serviceName) {
            case "gate-service":
                return 14000 + (webPort - 4000);
            case "lobby-service":
                return 15000 + (webPort - 5000);
            case "game-service":
                return 16000 + (webPort - 6000);
            default:
                return 0;
        }
    }
    
    /**
     * 生成多实例配置建议
     */
    public void generateMultiInstanceConfig() {
        log.info("=== 多实例配置建议 ===");
        
        String serviceType = getServiceTypeFromName(serviceName);
        log.info("服务类型: {}", serviceType);
        
        log.info("建议的多实例配置:");
        for (int i = 0; i < 3; i++) {
            int webPort = getBaseWebPort(serviceName) + i;
            int grpcPort = getBaseGrpcPort(serviceName) + i;
            int serverId = getBaseServerId(serviceName) + i;
            
            log.info("实例{}: Web端口={}, gRPC端口={}, 服务器ID={}", 
                    i + 1, webPort, grpcPort, serverId);
        }
        
        log.info("=== 配置建议完成 ===");
    }
    
    /**
     * 从服务名称获取服务类型
     */
    private String getServiceTypeFromName(String serviceName) {
        if (serviceName.contains("gate")) return "Gate";
        if (serviceName.contains("lobby")) return "Lobby";
        if (serviceName.contains("game")) return "Game";
        return "Unknown";
    }
    
    /**
     * 获取基础Web端口
     */
    private int getBaseWebPort(String serviceName) {
        switch (serviceName) {
            case "gate-service": return 4000;
            case "lobby-service": return 5000;
            case "game-service": return 6000;
            default: return 0;
        }
    }
    
    /**
     * 获取基础gRPC端口
     */
    private int getBaseGrpcPort(String serviceName) {
        switch (serviceName) {
            case "gate-service": return 14000;
            case "lobby-service": return 15000;
            case "game-service": return 16000;
            default: return 0;
        }
    }
    
    /**
     * 获取基础服务器ID
     */
    private int getBaseServerId(String serviceName) {
        switch (serviceName) {
            case "gate-service": return 1001;
            case "lobby-service": return 2001;
            case "game-service": return 3001;
            default: return 0;
        }
    }
} 